/*
 * Base worker class, is a thread and runs one job at a time
 * 
 */
package workers;

import managers.BaseManager;
import jobs.BaseJob;

public class BaseWorker extends Thread 
{
	private BaseJob mJob; // holds a job, worker may do one job at a time
	
	private volatile boolean mRunning = true; // false means thread will die
	private volatile boolean mAbort = false; // emergency stop, may kill the thread before the job is done
	
	private BaseManager mManager; // reference to it's manager
	
	public BaseWorker( String name )
	{
		Thread.currentThread().setName(name);
	}

	public void run()
	{
		while ( mRunning )
		{
			if ( hasJob() )
			{
				doJob();
				removeJob();
				
				mManager.releaseLoad(); // notifies it's manager that it no longer has work to do 							
			}
			
			/* abort point */
			if ( mAbort )
			{
				break;
			}
			
			synchronized ( this )
			{
				/* if no job has been provided, the thread goes to sleep */
				if ( !hasJob() && mRunning )
				{
					try 
					{
						wait();
					} 
					catch (InterruptedException e) 
					{
						e.printStackTrace();
					}
				}
			}
		}
		
		//System.out.println(Thread.currentThread().getName() + ": Dying!");
	}
	
	/* sets this worker assigned manager */
	public void setManager( BaseManager manager )
	{
		mManager = manager;
	}
	
	/* Assign job */
	public boolean setJob( BaseJob job )
	{
		mJob = job;			
		return true;
	}
	
	/* remove job */
	private boolean removeJob()
	{	
		mJob = null;
		return true;
	}
	
	/*call jobs run method */
	private void doJob()
	{
		mJob.run();
	}

	/* returns true if worker has a job assigned */
	public boolean hasJob()
	{
		if ( mJob == null )
		{
			return false;
		}
		
		return true;
	}
	
	public void stopProcess()
	{
		mRunning = false;
		
		synchronized ( this )
		{
			this.notify();
		}
	}
	
	public void forcedStopProcess()
	{
		mRunning = false;
		mAbort = true;
	}
}